#ifndef _SYMTAB_
#define _SYMTAB_

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "utils.h"

#define NB_LOCALES sommet - base - cur_func_nb_args + 1

typedef enum { VARIABLE, FONCTION } metatype;
typedef enum { INT_VAR, INT_ARRAY } ttype;
typedef enum { RET_VOID, RET_INT } returntype;

typedef struct { /* Variable */      
  int intval;   
  char *adresse;    
  bool isstatic;
} variable;

typedef struct { /* Argument de fonction */
  char *nom;
  ttype type;
} arguments;

typedef struct { /* Fonction */
  returntype rettype;
  int nb_args;
  arguments *args;
  bool visited;
} function; 

typedef struct { /* Symbole */
  char *nom;
  metatype mtype;
  union {
    variable *var;
    function *func;
  } content;
} symbole;

#define var_val      content.var->intval
#define var_static   content.var->isstatic
#define var_adresse  content.var->adresse
#define func_rettype content.func->rettype
#define func_nb_args content.func->nb_args
#define func_args    content.func->args
#define func_visited content.func->visited

symbole *dico;
static int max, sommet, base;
/* 
   cur_func_nb_args : Quand on est dans une fonction, donc une table locale, le nb
   d'arguments de la fonction est nécessaire pour connaître l'adresse à utiliser
   en assembleur. Ça sert aussi à déterminer l'espace à réserver pour %esp en début
   de fonction.
*/
static int cur_func_nb_args;
/*
  current_func : Indice, dans le dictionnaire, de la fonction en cours de parcours, donc celle qui a une table locale. -1 quand on est dans l'espace global.
*/
static int current_func = -1;

void creer_dico();
void agrandir_dico();
void add_variable(char *nom, bool isstatic);
void add_array(char *nom, int size, bool isstatic);
//void add_func(char *nom, int size, bool isstatic);
void add_prototype(returntype rettype, char *nom, arguments *args);
void add_entete(returntype rettype, char *nom, arguments *args);
symbole * lookup_decl(char *nom);
symbole * lookup_exec(char *nom);
void modifier (char *nom, int valeur);
void debut_local();
void fin_local();

#endif


